# Title     : TODO
# Objective : TODO
# Created by: Administrator
# Created on: 2019/6/18

library(gplots)
library(Hmisc)
library(optparse)
library(ropls)
library(magrittr)
library(ComplexHeatmap)
library(tools)
library(ppcor)
library(tidyverse)

option_list <- list(
  make_option("--i", default = "AllMet_Raw.txt", type = "character", help = "metabolite data file"),
  make_option("--g", default = "true_SampleInfo.csv", type = "character", help = "sample group file"),
  make_option("--ef", default = "extra_data.txt", type = "character", help = "metabolite data file"),
  make_option("--confounder", default = "confounder_data.txt", type = "character", help = "confounder data file"),
  make_option("--config", default = "calculate_config.txt", type = "character", help = "config file")
)
opt <- parse_args(OptionParser(option_list = option_list))

args <- commandArgs(trailingOnly = F)
scriptPath <- dirname(sub("--file=", "", args[grep("--file", args)]))
source(str_c(scriptPath, "/base.R"))

createWhenNoExist <- function(f) {
  !dir.exists(f) && dir.create(f)
}

configData <- read_tsv(opt$config, col_names = F) %>%
  set_colnames(c("arg", "value"))

corP <- configGet(configData, "p") %>%
  as.numeric()
corFdr <- configGet(configData, "fdr") %>%
  as.numeric()
cor <- configGet(configData, "coe") %>%
  as.numeric()
corMethod <- configGet(configData, "corMethod")
fdrMethod <- configGet(configData, "fdrMethod")

orignalData <- read_tsv(opt$i)


data <- orignalData %>%
  gather("ID", "Value", -Metabolite) %>%
  spread(Metabolite, "Value")

parent <- "./"
createWhenNoExist(parent)

finalParent <- paste0("./")

extraData <- read_tsv(opt$ef) %>%
  rename(Metabolite = 1) %>%
  gather("ID", "Value", -Metabolite) %>%
  spread(Metabolite, "Value")

confounderData <- read_tsv(opt$confounder) %>%
  rename(Metabolite = 1) %>%
  gather("ID", "Value", -Metabolite) %>%
  spread(Metabolite, "Value")

dataIds <- data$ID
extraIds <- extraData$ID
confounderIds <- confounderData$ID
interIds <- Reduce(intersect, list(dataIds, extraIds, confounderIds))

extraData <- extraData %>%
  filter(ID %in% interIds) %>%
  arrange(factor(ID, levels = interIds))

confounderData <- confounderData %>%
  filter(ID %in% interIds) %>%
  arrange(factor(ID, levels = interIds))

inData <- data %>%
  filter(ID %in% interIds) %>%
  arrange(factor(ID, levels = interIds))

print("=in=")
inData

inData <- inData %>%
  as.data.frame()


if (nrow(inData) < 2) {
  stop("交集数据过少（小于2）")
}

pcorData <- zd_pcor(left = inData, right = extraData, confounding = confounderData,method = corMethod)

allData <- tibble(Node1 = pcorData$pair_1, Node2 = pcorData$pair_2, r = pcorData$r, P = pcorData$p) %>%
  mutate_at(vars(c("r")), function(x) {
    ifelse(is.na(x), 0, x)
  }) %>%
  mutate_at(vars(c("P")), function(x) {
    ifelse(is.na(x), 1, x)
  }) %>%
  mutate(FDR = p.adjust(P, method = fdrMethod))

allData

if (nrow(allData) == 0) {
  next
}

createWhenNoExist(finalParent)
corData <- allData %>%
  select(c("Node1", "Node2", "r")) %>%
  spread(Node1, "r") %>%
  mutate_at(vars(-c("Node2")), function(x) {
    ifelse(is.na(x), 0, x)
  }) %>%
  rename(` ` = Node2)

corData

write.csv(corData, paste0(finalParent, "/r_Matrix.csv"), quote = T, row.names = F)

pData <- allData %>%
  select(c("Node1", "Node2", "P")) %>%
  spread(Node1, "P") %>%
  mutate_at(vars(-c("Node2")), function(x) {
    ifelse(is.na(x), 1, x)
  }) %>%
  rename(` ` = Node2)
write_csv(pData, paste0(finalParent, "/P_Matrix.csv"))

fdrData <- allData %>%
  select(c("Node1", "Node2", "FDR")) %>%
  spread(Node1, "FDR") %>%
  mutate_at(vars(-c("Node2")), function(x) {
    ifelse(is.na(x), 1, x)
  }) %>%
  rename(` ` = Node2)
write.csv(fdrData, paste0(finalParent, "/Corrected_P_Matrix.csv"), quote = T, row.names = F)

edgeData <- allData %>%
  filter(P < corP & FDR < corFdr & abs(r) > cor) %>%
  filter(Node1 != Node2) %>%
  mutate(distName = {
    Node1 %>%
      map2_chr(Node2, function(x, y) {
        vec <- c(x, y) %>%
          sort()
        str_c(vec, collapse = ";")
      })
  }) %>%
  distinct(distName, .keep_all = T) %>%
  select(-c("distName")) %>%
  arrange(desc(abs(r)))
write_csv(edgeData, paste0(finalParent, "/Network_Edges_for_Cytoscape.csv"))

nodes <- unique(c(edgeData$Node1, edgeData$Node2))
infoData <- tibble(Node = nodes) %>%
  mutate(Size = {
    Node %>%
      map_int(function(x) {
        edgeData %>%
          filter(Node1 == x | Node2 == x) %>%
          nrow()
      })
  })
write_csv(infoData, paste0(finalParent, "/Network_Nodes_for_Cytoscape.csv"))


